<template>
  <div class="login-wrap">
    <el-card class="login-card" shadow="always">
      <h2>FAMES 管理端登录</h2>
      <el-form :model="form" :rules="rules" ref="formRef" label-position="top" size="large" @submit.prevent="onSubmit">
        <el-form-item label="用户名" prop="username">
          <el-input v-model="form.username" autocomplete="username" />
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input v-model="form.password" type="password" autocomplete="current-password" />
        </el-form-item>
        <el-form-item label="安全校验" prop="slider">
          <div class="captcha-slider" :class="{ passed: sliderOk }">
            <span class="captcha-text" v-if="!sliderOk">拖动滑块完成验证</span>
            <span class="captcha-text success" v-else>验证通过</span>
            <el-slider
              v-model="form.slider"
              :min="0"
              :max="100"
              :step="1"
              :show-tooltip="false"
              @change="onSliderChange"
            />
          </div>
        </el-form-item>
        <el-form-item class="actions">
          <el-button type="primary" size="large" :disabled="!sliderOk" :loading="auth.loading" @click="onSubmit">登录</el-button>
        </el-form-item>
      </el-form>
    </el-card>
  </div>
</template>

<script setup lang="ts">
import { reactive, ref, computed } from 'vue'
import { ElMessage } from 'element-plus'
import { useRouter } from 'vue-router'
import { useAuthStore } from '../store/auth'
import { useMenuStore } from '../store/menu'

const auth = useAuthStore()
const router = useRouter()
const form = reactive({ username: '', password: '', slider: 0 })
const formRef = ref()
const rules = {
  username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
  password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
  slider: [{ validator: (_: any, value: number, cb: Function) => (value === 100 ? cb() : cb(new Error('请完成滑动校验'))), trigger: 'change' }],
}

const sliderOk = computed(() => form.slider === 100)

const menu = useMenuStore()

const onSubmit = async () => {
  try {
    if (formRef.value) {
      // @ts-ignore Element Plus 回调式校验
      const isValid = await new Promise<boolean>((resolve) => formRef.value.validate((v: boolean) => resolve(v)))
      if (!isValid) return
    }
    await auth.login(form.username, form.password)
    // 登录后加载角色菜单并跳转到首个可访问路径
    try { await menu.loadTree() } catch {}
    const target = menu.firstAdminPath || '/admin/dashboard'
    router.push(target)
  } catch (e: any) {
    const msg = e?.response?.status === 401 ? (e?.response?.data?.detail || '用户名或密码错误') : '登录失败，请稍后重试'
    ElMessage.error(msg)
  }
}

// 滑块“吸附”到 100%，避免停在 99 的尴尬
function onSliderChange(v: number) {
  if (v >= 95) form.slider = 100
}
</script>

<style scoped>
.login-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  min-height: 0;
  padding: 0;
  background: linear-gradient(180deg, var(--bg-main, #fbfcfe), var(--bg-aside, #f7f9fc));
}
.login-card { width: min(480px, 92vw); }
:deep(.login-card .el-card__body){ padding: 28px; min-height: 420px; display: flex; flex-direction: column; }
:deep(.content-card) { padding: 0; border: none; background: transparent; }
.login-card { border: 1px solid var(--border-soft, #e9edf3); border-radius: 16px; box-shadow: 0 12px 28px rgba(17, 24, 39, 0.08); }
h2 {
  font-size: 22px;
  font-weight: 600;
  color: var(--text-primary, #1f2328);
  margin: 4px 0 12px;
}
.actions { text-align: right; }
/* 右对齐按钮：Element Plus 表单内容默认为 flex，这里强制靠右 */
.actions :deep(.el-form-item__content) {
  display: flex;
  justify-content: flex-end;
}
/* 保证输入框占满宽度且一致 */
:deep(.el-input__wrapper) { width: 100%; }
/* 表单间距优化 */
:deep(.el-form-item) { margin-bottom: 16px; }
/* 滑动校验美化 */
.captcha-slider { position: relative; height: 40px; --el-slider-height: 40px; }
.captcha-slider :deep(.el-slider) { padding: 0; }
.captcha-slider :deep(.el-slider__runway) {
  position: relative;
  z-index: 0;
  height: 40px;
  border-radius: 10px;
  background: #eef2f7;
  border: none;
  box-sizing: border-box;
  overflow: hidden; /* 裁剪内部进度条，避免溢出导致上下对不齐 */
  transition: background 0.25s ease, border-color 0.25s ease;
}
.captcha-slider :deep(.el-slider__bar) {
  position: absolute;
  z-index: 1;
  height: 100%;
  top: 0 !important;
  transform: none !important;
  margin-top: 0 !important;
  border-radius: 10px;
  background: linear-gradient(90deg, #c7d2fe, #a5b4fc);
}
.captcha-slider :deep(.el-slider__button-wrapper) {
  z-index: 3;
  height: var(--el-slider-height);
  top: calc(var(--el-slider-height) / 2) !important;
  transform: translate(-50%, -50%) !important;
}
.captcha-slider :deep(.el-slider__button) {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  background: #fff;
  border: 1px solid #cbd5e1;
  box-shadow: 0 6px 16px rgba(17, 24, 39, 0.12);
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box; /* 包含边框在高度计算内，避免溢出轨道 */
}
.captcha-slider :deep(.el-slider__button::after) {
  content: '→';
  display: inline-block;
  color: #4f46e5;
  font-size: 18px;
  font-weight: 700;
  line-height: 1;
}
.captcha-text {
  position: absolute;
  left: 0; right: 0;
  top: 50%;
  transform: translateY(-50%);
  text-align: center;
  z-index: 2; /* 高于条但低于手柄 */
  color: #6b7280;
  pointer-events: none;
}
.captcha-text.success { color: #059669; font-weight: 600; }
.captcha-slider.passed :deep(.el-slider__runway) {
  border-color: #10b981;
  background: #ecfdf5;
}
.captcha-slider.passed :deep(.el-slider__bar) {
  background: linear-gradient(90deg, #34d399, #10b981);
}
.captcha-slider.passed :deep(.el-slider__button) {
  border-color: #10b981;
}
.captcha-slider.passed :deep(.el-slider__button::after) {
  content: '✔';
  color: #10b981;
}
@media (max-width: 768px) {
  .login-card { border-radius: 12px; }
}

/* 修复滑块容器宽度与提示文字换行问题 */
.captcha-slider { width: 100%; }
.captcha-slider :deep(.el-slider) { width: 100%; display: block; height: 40px; }
.captcha-text { white-space: nowrap; line-height: 40px; }
</style>
